package org.ws.httphelper.support.parser.field.operator;

import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.ws.httphelper.model.field.ParseField;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class CssQueryParseOperator extends AbstractParseOperator<Element> {

    @Override
    public String parseString(String body, ParseField fieldInfo) throws Exception {
        Document doc = parseDocument(body);
        return evaluateString(fieldInfo,doc);
    }

    @Override
    public List parseList(String body, ParseField listFieldInfo) throws Exception {
        Document doc = parseDocument(body);
        return evaluateList(listFieldInfo,doc);
    }

    @Override
    public Map parseMap(String body, ParseField mapFieldInfo) throws Exception {
        Document doc = parseDocument(body);
        return evaluateMap(mapFieldInfo,doc);
    }

    private Document parseDocument(String body){
        return Jsoup.parse(body);
    }

    @Override
    protected String evaluateString(ParseField fieldInfo, Element element){
        Elements elements = element.select(fieldInfo.getParseExpression());
        if(StringUtils.isNotBlank(fieldInfo.getAttribute())){
            return elements.attr(fieldInfo.getAttribute());
        }
        else {
            return elements.text();
        }
    }

    @Override
    protected List evaluateList(ParseField fieldInfo, Element element)throws Exception {
        Elements elements = element.select(fieldInfo.getParseExpression());
        List resultList = new ArrayList();
        if(elements != null){
            if(fieldInfo.hasChild()){
                List<ParseField> childFieldList = fieldInfo.getChildFieldInfoList();
                for(Element item:elements){
                    Map map = new HashMap();
                    evaluateChild(childFieldList,item,map);
                    resultList.add(map);
                }
            }
            else {
                for(Element item:elements){
                    resultList.add(evaluateString(fieldInfo,item));
                }
            }
        }
        return resultList;
    }

    @Override
    protected Map evaluateMap(ParseField fieldInfo, Element element)throws Exception {
        Elements elements = element.select(fieldInfo.getParseExpression());
        Element first = elements.first();
        if(fieldInfo.hasChild()){
            Map map = new HashMap();
            List<ParseField> childFieldList = fieldInfo.getChildFieldInfoList();
            evaluateChild(childFieldList,first,map);
            return map;
        }
        return null;
    }
}
